var jsFactory = {
    /*--------------------------
     * When create is called it builds the object specified in the first
     * argument.
     * Any items in the optional second parameter will update
     * the object before returning it.
     * Any items passed in the third has will be used for the constructor
     * of the object to be built
     *
     * @param {String}
     * @param {Hash} [Optional]
     * @param {Hash} [Optional]
     * @return Object
     */
	create : function(){
		if (arguments[0] == undefined) {
			return null;
		}
		argsString = "";
		
		var intialArgs = this._fillBaseInitialArgs(arguments[2])
		
		var baseObject = eval(
		"new " + arguments[0] + "(" + intialArgs + ")" 
		);
		
		this._fillDefaultValues(baseObject, arguments[0]);
		
		if (arguments[1] == undefined) {
			return baseObject;
		} else {
			this._fillPassedValues(baseObject, arguments[1])
		}
		
		return baseObject;
	},
    /*--------------------------
     * When create is called it builds the type of HTML element in the first
     * argument.
     *
     * second argument are all the element attributes to be loaded.
     *
     * Third argument attaches the element created to a parent.
     *
     * @param {String}
     * @param {Hash} [Optional]
     * @param {String} [Optional]
     * @return Element
     */
	createHtmlElement : function() {
		if (arguments[0] == undefined) {
			return null;
		}
		
		var parent;
		var element = document.createElement(arguments[0]);
		
		this._fillHTMLAttributes(element, arguments[1])
		
		if (arguments[2] != undefined) {
			this._setElementParent(arguments[2], element);
		}
		
		return element;
	},
    /*--------------------------
     * Attaches the element to a DOM parent
     *
     * @private
     * @param {String, Object} args
     * @param {Element} element
     * @return Element
     */
	_setElementParent : function(args, element) {
		var parent;
		if (typeof args == "string") {
			parent = document.getElementById(args);
			parent.appendChild(element);
		} else if (typeof args == "object"){
			parent = args;
			parent.appendChild(element);
		}
		return parent;
	},
    /*--------------------------
     * Fills the HTML element with it's attributes
     *
     * @private
     * @param {Element} object
     * @param {Hash} args
     * @return undefined
     */
	_fillHTMLAttributes : function(object, args) {
		for (var key in args) {
			if (key.toString().toLowerCase() == "innerhtml") {
				object.innerHTML = args[key];
			} else {
				object.setAttribute(key.toString(), args[key].toString());
			}	
		}
	},
    /*--------------------------
     * Makes sure to make the constructor arguments a string
     * before using in the base object constructor.
     *
     * @private
     * @param {Hash} args
     * @return Hash or undefined
     */
	_fillBaseInitialArgs : function(args) {
		if (args != undefined) {
			for (var i = 0; i < args.length; i++) {
				if (typeof args[i] == "string") {
					args[i] = '"' + args[i].toString() + '"';
				}
			}
		} else {
			args = undefined;
		}
		return args;
	},
    /*--------------------------
     * The object is filled with the corresponding data from the test fixture
     * if any
     *
     * @private
     * @param {Object} object
     * @param {String} name
     * @return undefined
     */
	_fillDefaultValues : function(object, name) {
		try {
			var defaultValues = eval("build_"  + name.toString().toLowerCase())();
		
			for (var key in defaultValues) {
				object[key] = defaultValues[key];
			}
		} catch(e) {
			//No build function apparently
		}
	},
    /*--------------------------
     * Fill the object with given values from the hash
     *
     * @private
     * @param {Object} object
     * @param {Hash} args
     * @return undefined
     */
	_fillPassedValues : function (object, args) {
		for (var key in args) {
			object[key] = args[key];
		}
	}
}
